﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Service;
using MODEL;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation;
using GalaSoft.MvvmLight.Views;
using Common;
using System.ComponentModel;
using GalaSoft.MvvmLight.Ioc;

namespace ViewModel.StationManager
{
    public class StationSettingViewModel : ViewModelBase
    {
        public ICommand DeleteCommand { get; set; }
        public ICommand UpdateCommand { get; set; }
        public ICommand ConfigElementCommand { get; set; }
        public ICommand DetailCommand { get; set; }
        public ICommand AddCommand { get; set; }
        public ICommand BatchDeleteCommand { get; set; }


        private readonly string m_NonSelectStationType = "未选中站点类型";
        private string m_CurrentStationType;
        public string CurrentStationType
        {
            get { return this.m_CurrentStationType; }
            set { this.m_CurrentStationType = value; base.RaisePropertyChanged(() => CurrentStationType); }
        }
        private List<string> m_StationTypeList;
        public List<string> StationTypeList
        {
            get { return this.m_StationTypeList; }
            set { this.m_StationTypeList = value; base.RaisePropertyChanged(() => this.StationTypeList); }
        }

        private readonly Province m_NonSelectProvince = new Province { ProvinceName = "未选中省" };
        private Province m_CurrentProvince;
        public Province CurrentProvince
        {
            get { return this.m_CurrentProvince; }
            set { m_CurrentProvince = value; base.RaisePropertyChanged(() => this.CurrentProvince); }
        }
        private List<Province> m_ProvinceList;
        public List<Province> ProvinceList
        {
            get { return this.m_ProvinceList; }
            set { this.m_ProvinceList = value; base.RaisePropertyChanged(() => this.ProvinceList); }
        }

        private readonly City m_NonSelectCity = new City { CityName = "未选中市" };
        private City m_CurrentCity;
        public City CurrentCity
        {
            get { return this.m_CurrentCity; }
            set { this.m_CurrentCity = value; base.RaisePropertyChanged(() => this.CurrentCity); }
        }
        private List<City> m_CityList;
        public List<City> CityList
        {
            get { return this.m_CityList; }
            set { this.m_CityList = value; base.RaisePropertyChanged(() => this.CityList); }
        }

        private readonly County m_NonSelectCounty = new County { CountyName = "未选中区" };
        private County m_CurrentCounty;
        public County CurrentCounty
        {
            get { return this.m_CurrentCounty; }
            set { this.m_CurrentCounty = value; base.RaisePropertyChanged(() => this.CurrentCounty); }
        }
        private List<County> m_CountyList;
        public List<County> CountyList
        {
            get { return this.m_CountyList; }
            set { this.m_CountyList = value; base.RaisePropertyChanged(() => this.CountyList); }
        }

        private List<StationInfo> m_StationInfos;
        public List<StationInfo> StationInfos
        {
            get { return this.m_StationInfos; }
            set { this.m_StationInfos = value; base.RaisePropertyChanged(() => this.StationInfos); }
        }

        private Dictionary<int, List<City>> m_CityDictionary;
        private Dictionary<int, List<County>> m_CountyDictionary;

        private IStationServcie m_StationService;
        private IAreaService m_AreaService;

        public StationSettingViewModel(IStationServcie stationService, IAreaService areaService)
        {
            this.m_StationService = stationService;
            this.m_AreaService = areaService;
            this.AddCommand = new RelayCommand(ShowEditStationForm);
            this.UpdateCommand = new RelayCommand<StationInfo>(ShowEditStationForm);
            this.DeleteCommand = new RelayCommand<int>(DeleteStation);
            this.BatchDeleteCommand = new RelayCommand(BatchDeleteStation);
            this.DetailCommand = new RelayCommand<StationInfo>(ShowDetailForm);
            this.ConfigElementCommand = new RelayCommand<StationInfo>(ShowElementConfigForm);

            RefreshData(() => this.PropertyChanged += OnPropertyChange);
        }

        public void OnPropertyChange(object sender, PropertyChangedEventArgs e)
        {           
            if (e.PropertyName == "CurrentProvince")
            {
                List<City> cityList = new List<City>() { this.m_NonSelectCity };
                if (this.CurrentProvince != m_NonSelectProvince)
                {
                    List<City> citys = new List<City>();
                    if (this.m_CityDictionary.TryGetValue(this.CurrentProvince.Id, out citys))
                    {
                        cityList.AddRange(citys);
                    }
                }
                this.CurrentCity = m_NonSelectCity;
                this.CityList = cityList;
                QueryStation();
            }

            if (e.PropertyName == "CurrentCity")
            {
                List<County> countyList = new List<County> { this.m_NonSelectCounty };
                if (this.CurrentCity != m_NonSelectCity)
                {
                    List<County> countys = new List<County>();
                    if (this.m_CountyDictionary.TryGetValue(this.CurrentCity.CityId, out countys))
                    {
                        countyList.AddRange(countys);
                    }
                }
                this.CurrentCounty = this.m_NonSelectCounty;
                this.CountyList = countyList;
                QueryStation();
            }

            if (e.PropertyName == "CurrentCounty" || e.PropertyName == "CurrentStationType")
            {
                QueryStation();
            }
        }

        public async void RefreshData(Action afterAction = null)
        {
            try
            {
                List<string> stationTypeList = new List<string> { this.m_NonSelectStationType };
                 stationTypeList.AddRange(EnumHelper.GetEnumDescriptionList(typeof(StationTypeEnum)));
                this.StationTypeList = stationTypeList;
                
                List<Province> provinces = new List<Province>() { this.m_NonSelectProvince };
                provinces.AddRange(await m_AreaService.GetAllProvinceList());
                this.ProvinceList = provinces;

                this.CityList = new List<City> { this.m_NonSelectCity };
                this.CountyList = new List<County> { this.m_NonSelectCounty };

                this.m_CityDictionary = (await m_AreaService.GetAllCityList()).GroupBy(city => city.ProvinceId).ToDictionary(cityGroyup => cityGroyup.Key, cityGroup => cityGroup.ToList());

                this.m_CountyDictionary = (await m_AreaService.GetAllCountyList()).GroupBy(county => county.CityId).ToDictionary(countyGroup => countyGroup.Key, countyGroup => countyGroup.ToList());

                this.CurrentStationType = this.m_NonSelectStationType;
                this.CurrentProvince = this.m_NonSelectProvince;
                this.CurrentCity = this.m_NonSelectCity;
                this.CurrentCounty = this.m_NonSelectCounty;

                QueryStation();

                if (afterAction != null)
                {
                    afterAction.Invoke();
                }
            }
            catch (Exception ex)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowError("加载数据失败", "错误", "确定", null);
                Log.WriteException(ex);
            }
        }

        private async void QueryStation()
        {
            StationQueryCriteria criteria = new StationQueryCriteria();
           
            if (this.CurrentProvince != null && this.CurrentProvince != m_NonSelectProvince)
            {
                criteria.ProvinceName = this.CurrentProvince.ProvinceName;
            }

            if (this.CurrentCity != null && this.CurrentCity != m_NonSelectCity)
            {
                criteria.CityName = this.CurrentCity.CityName;
            }

            if (this.CurrentCounty != null && this.CurrentCounty != m_NonSelectCounty)
            {
                criteria.CountyName = this.CurrentCounty.CountyName;
            }

            if (this.CurrentStationType != null && this.CurrentStationType != m_NonSelectStationType)
            {
                criteria.StationType = this.CurrentStationType;
            }

            if (!AppSetting.Instance.User.role.IsAdmin)
            {
                criteria.UserId = AppSetting.Instance.User.UserId;
            }

            try
            {
                this.StationInfos = (await this.m_StationService.QueryStationsAsync(criteria)).ToList();
            }
            catch (Exception ex)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowError("获取站点信息失败", "错误", "确定", null);
                Log.WriteException(ex);
            }
        }

        public void ShowEditStationForm()
        {
            StationSettingEditViewModel vm = SimpleIoc.Default.GetInstanceWithoutCaching<StationSettingEditViewModel>();
            this.MessengerInstance.Send(vm, "StationSetting_ShowEditForm");
        }

        public void ShowEditStationForm(StationInfo stationInfo)
        {
            StationSettingEditViewModel vm = SimpleIoc.Default.GetInstanceWithoutCaching<StationSettingEditViewModel>();
            vm.StationInfo = stationInfo;
            this.MessengerInstance.Send(vm, "StationSetting_ShowEditForm");
        }

        public async void DeleteStation(int id)
        {
            try
            {
                bool IsConfirm = await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("当前数据即将被删除，是否确认？", "提示", "确认", "取消", null);
                if (!IsConfirm)
                {
                    return;
                }
                Task task = this.m_StationService.DeleteStations(new List<int> { id });
                task.Wait();
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("删除成功", "提示");
                RefreshData();
            }
            catch (Exception ex)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowError("删除失败", "错误", "确定", null);
                Log.WriteException(ex);
            }
        }

        public async void BatchDeleteStation()
        {
            try
            {
                List<StationInfo> selectedStationInfos = this.StationInfos.Where(stationInfo => stationInfo.IsChecked).ToList();
                if (!selectedStationInfos.SafeCheck())
                {
                    await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("未选中任何数据", "提示");
                    return;
                }

                bool isComfirm = await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("所选数据将被全部删除，是否确认？", "提示", "确认", "取消", null);
                if (!isComfirm)
                {
                    return;
                }
                Task task = this.m_StationService.DeleteStations(selectedStationInfos.Select(stationInfo => stationInfo.StationId).ToList());
                task.Wait();
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowMessage("删除成功", "提示");
                RefreshData();
            }
            catch (Exception ex)
            {
                await ServiceLocator.Current.GetInstance<IDialogService>().ShowError("删除失败", "错误", "确定", null);
                Log.WriteException(ex);
            }
        }

        public void ShowElementConfigForm(StationInfo stationInfo)
        {
            StationElementConfigViewModel vm = SimpleIoc.Default.GetInstanceWithoutCaching<StationElementConfigViewModel>();
            vm.StationInfo = stationInfo;
            this.MessengerInstance.Send<ViewModelBase>(vm, "StationSetting_ShowElementConfigForm");
        }

        public void ShowDetailForm(StationInfo stationInfo)
        {
            StationDetailViewModel vm = SimpleIoc.Default.GetInstanceWithoutCaching<StationDetailViewModel>();
            vm.StationInfo = stationInfo;
            this.MessengerInstance.Send<ViewModelBase>(vm, "StationSetting_ShowDetailForm");
        }
    }
}
